#if ((FEATURE_MODE == 2) || (FEATURE_MODE == 0))
/**
 @file sys_usw_ptp.h

 @date 2012-9-17

 @version v2.0

  The file defines Macro, stored data structure for PTP module
*/
#ifndef _SYS_USW_PTP_H
#define _SYS_USW_PTP_H
#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************************
 *
 * Header Files
 *
****************************************************************************/
#include "sal.h"
#include "ctc_const.h"
#include "ctc_ptp.h"
#include "ctc_interrupt.h"
#include "ctc_vector.h"

/****************************************************************************
*
* Defines and Macros
*
****************************************************************************/
#define SYS_PTP_MAX_DOMAIN_NUM 2
#define SYS_PTP_MAX_SESSION_NUM 96
#define SYS_PTP_SESSION_NUM_PER_DOMAIN 48

#define SYS_AT_PTP_TIEM_INTF_GPIO_0 0
#define SYS_AT_PTP_TIEM_INTF_GPIO_1 1
#define SYS_AT_PTP_TIEM_INTF_SYNC_PULSE_0 2
#define SYS_AT_PTP_TIEM_INTF_SYNC_PULSE_1 3
#define SYS_AT_PTP_TIEM_INTF_TOD_1PPS 4
#define SYS_AT_PTP_TIEM_INTF_NONE 8

#define SYS_PTP_DBG_OUT(level, FMT, ...) \
        do { \
            CTC_DEBUG_OUT(ptp, ptp, PTP_PTP_SYS, level, FMT, ##__VA_ARGS__); \
        } while (0)
    
#define SYS_PTP_INIT_CHECK() \
        do { \
            LCHIP_CHECK(lchip); \
            if (NULL == p_usw_ptp_master[lchip]){ \
                SYS_PTP_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " Feature not initialized \n");\
                return CTC_E_NOT_INIT;\
     } \
        } while (0)
    
#define SYS_PTP_RX_SOURCE_CHECK(source) \
        do { \
            if (source >= MCHIP_CAP(SYS_CAP_PTP_CAPTURED_RX_SOURCE)){ \
                SYS_PTP_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Local phyport is not exist \n");\
                return CTC_E_NOT_EXIST;\
     } \
        } while (0)
    
#define SYS_PTP_TX_SEQ_ID_CHECK(seq_id) \
        do { \
            if (seq_id >= MCHIP_CAP(SYS_CAP_PTP_CAPTURED_TX_SEQ_ID)){ \
                return CTC_E_INVALID_PARAM; } \
        } while (0)
    
#define SYS_PTP_RX_SEQ_ID_CHECK(seq_id) \
        do { \
            if (seq_id >= MCHIP_CAP(SYS_CAP_PTP_CAPTURED_RX_SEQ_ID)){ \
                return CTC_E_INVALID_PARAM; } \
        } while (0)


#define PTP_LOCK \
    if (p_usw_ptp_master[lchip]->p_ptp_mutex) sal_mutex_lock(p_usw_ptp_master[lchip]->p_ptp_mutex)
#define PTP_UNLOCK \
    if (p_usw_ptp_master[lchip]->p_ptp_mutex) sal_mutex_unlock(p_usw_ptp_master[lchip]->p_ptp_mutex)

#define PTP_CB_LOCK \
        if (p_ptp_cb_mutex) sal_mutex_lock(p_ptp_cb_mutex)
#define PTP_CB_UNLOCK \
        if (p_ptp_cb_mutex) sal_mutex_unlock(p_ptp_cb_mutex)


/****************************************************************************
*
* Data structures
*
****************************************************************************/

struct sys_ptp_session_s
{
    uint32 nhid1;/*nexthop for event message*/
    uint32 nhid2;/*nexthop for general message*/
    uint32 gport;
};
typedef struct sys_ptp_session_s sys_ptp_session_t;

/**
 @brief  Define sys layer ptp global configure data structure
*/
struct sys_ptp_master_s
{
    sal_mutex_t* p_ptp_mutex;
    ctc_ptp_device_type_t device_type;
    ctc_vector_t* p_tx_ts_vector;
    ctc_vector_t* p_rx_ts_vector;
    CTC_INTERRUPT_EVENT_FUNC g_p_tx_ts_capture_cb;
    sal_task_t* p_polling_tod;
    sys_ptp_session_t* session;//[SYS_PTP_MAX_SESSION_NUM];

    uint64 session_en_bmp[SYS_PTP_MAX_DOMAIN_NUM];
    uint32 tod_1pps_delay;/**< 1pps delay between Tod master and slave*/
    uint32 tod_1pps_delay_nano_ns;/**< 1pps delay between Tod master and slave*/
    uint32 tod_1pps_thrd; /**< only for CTC_PTP_INTF_MODE_1PPS_ONLY*/
    uint32 drift_nanoseconds;

    uint16 cache_aging_time;  /**< aging time for TS, unit:seconds*/
    uint16 alloced_cpu_reason;
    uint8  ptp_opf_type;
    uint8 tod_1pps_mode;
    uint8 tod_1pps_flex_en;
    uint8 tod_1pps_duty;
    uint8 sync_mode[SYS_PTP_MAX_DOMAIN_NUM];
    uint8 quanta;
    uint8 intf_selected;
    uint8 hw_mode;       /*0:process in HCPU,1:process in MCPU*/
    uint8 t1_t2_count;   /*count for ecpu report ts valid*/
    uint8 t3_t4_count;
};
typedef struct sys_ptp_master_s sys_ptp_master_t;

enum sys_ptp_msg_type_e
{
    SYS_PTP_EVENT_MESSAGE,
    SYS_PTP_GENERAL_MESSAGE,
    SYS_PTP_MSG_TYPE_MAX
};
typedef enum sys_ptp_msg_type_e sys_ptp_msg_type_t;

/****************************************************************************
 *
* Function
*
****************************************************************************/

/**
 @brief Initialize PTP module and set ptp default config
*/
extern int32
sys_usw_ptp_init(uint8 lchip, ctc_ptp_global_config_t* ptp_global_cfg);

/**
 @brief Set ptp property
*/
extern int32
sys_usw_ptp_set_global_property(uint8 lchip, ctc_ptp_global_prop_t property, uint32 value);

/**
 @brief Get ptp property
*/
extern int32
sys_usw_ptp_get_global_property(uint8 lchip, ctc_ptp_global_prop_t property, uint32* value);

/**
 @brief Get timestamp from free running clock
*/
extern int32
sys_usw_ptp_get_clock_timestamp(uint8 lchip, ctc_ptp_time_t* timestamp);

/**
 @brief Adjust offset for free running clock
*/
extern int32
sys_usw_ptp_adjust_clock_offset(uint8 lchip, ctc_ptp_time_t* offset);

/**
 @brief Set drift for free running clock
*/
extern int32
sys_usw_ptp_set_clock_drift(uint8 lchip, ctc_ptp_time_t* p_drift);

/**
 @brief Get drift for free running clock
*/
extern int32
sys_usw_ptp_get_clock_drift(uint8 lchip, ctc_ptp_time_t* p_drift);

/**
 @brief Set PTP device type
*/
extern int32
sys_usw_ptp_set_device_type(uint8 lchip, ctc_ptp_device_type_t device_type);

/**
 @brief Get PTP device type
*/
extern int32
sys_usw_ptp_get_device_type(uint8 lchip, ctc_ptp_device_type_t* device_type);

/**
 @brief Set adjust delay for PTP message delay correct
*/
extern int32
sys_usw_ptp_set_adjust_delay(uint8 lchip, uint32 gport, ctc_ptp_adjust_delay_type_t type, int64 value);

/**
 @brief Set adjust delay for PTP message delay correct
*/
extern int32
sys_usw_ptp_get_adjust_delay(uint8 lchip, uint32 gport, ctc_ptp_adjust_delay_type_t type, int64* value);

/**
 @brief  Set sync interface config
*/
extern int32
sys_usw_ptp_set_sync_intf(uint8 lchip, ctc_ptp_sync_intf_cfg_t* p_config);

/**
 @brief  Get sync interface config
*/
extern int32
sys_usw_ptp_get_sync_intf(uint8 lchip, ctc_ptp_sync_intf_cfg_t* p_config);

/**
 @brief  Set toggle time to trigger sync interface output syncColck signal
*/
extern int32
sys_usw_ptp_set_sync_intf_toggle_time(uint8 lchip, ctc_ptp_time_t* p_toggle_time);

/**
 @brief  Set toggle time to trigger sync interface output syncColck signal
*/
extern int32
sys_usw_ptp_get_sync_intf_toggle_time(uint8 lchip, ctc_ptp_time_t* p_toggle_time);

/**
 @brief  Get sync interface input time information
*/
extern int32
sys_usw_ptp_get_sync_intf_code(uint8 lchip, ctc_ptp_sync_intf_code_t* g_time_code);

/**
 @brief  Clear sync interface input time information
*/
extern int32
sys_usw_ptp_clear_sync_intf_code(uint8 lchip);

/**
 @brief  Set ToD interface config
*/
extern int32
sys_usw_ptp_set_tod_intf(uint8 lchip, ctc_ptp_tod_intf_cfg_t* config);

/**
 @brief  Get ToD interface config
*/
extern int32
sys_usw_ptp_get_tod_intf(uint8 lchip, ctc_ptp_tod_intf_cfg_t* config);

/**
 @brief  Set ToD interface output message config
*/
extern int32
sys_usw_ptp_set_tod_intf_tx_code(uint8 lchip, ctc_ptp_tod_intf_code_t* tx_code);

/**
 @brief  Get ToD interface output message config
*/
extern int32
sys_usw_ptp_get_tod_intf_tx_code(uint8 lchip, ctc_ptp_tod_intf_code_t* tx_code);

/**
 @brief  Get ToD interface input time information
*/
extern int32
sys_usw_ptp_get_tod_intf_rx_code(uint8 lchip, ctc_ptp_tod_intf_code_t* rx_code);

/**
 @brief  Clear ToD interface input time information
*/
extern int32
sys_usw_ptp_clear_tod_intf_code(uint8 lchip);

/**
 @brief  Get timestamp captured by local clock
*/
extern int32
sys_usw_ptp_get_captured_ts(uint8 lchip, ctc_ptp_capured_ts_t* p_captured_ts);


/**
 @brief  Add ptp clock type
*/
extern int32
sys_usw_ptp_add_device_clock(uint8 lchip, ctc_ptp_clock_t* clock);

/**
 @brief  Remove ptp clock type
*/
extern int32
sys_usw_ptp_remove_device_clock(uint8 lchip, ctc_ptp_clock_t* clock);

/**
 @brief  Deinit
*/
extern int32
sys_usw_ptp_deinit(uint8 lchip);

extern int32
sys_usw_ptp_add_session(uint8 lchip, ctc_ptp_session_t* ptp_session);

extern int32
sys_usw_ptp_remove_session(uint8 lchip, ctc_ptp_session_t* ptp_session);

extern int32
sys_usw_ptp_get_session(uint8 lchip, ctc_ptp_session_t* ptp_session);

extern int32
sys_usw_ptp_isr_tx_ts_capture(uint8 lchip, uint32 intr, void* p_data);
#ifdef __cplusplus
}
#endif

#endif

#endif

